import { Guid } from './../common/utils/guid';
import { Transaction } from "tiny-entity2";
import { IQueryObject } from "tiny-entity2/queryObject";
import { ApiDataContext } from "../domain/apiDataContext";
import { Organization } from "../domain/models/organization";
import { BaseService, QueryParamsBase } from "./baseService";
import { ServiceException } from "../common/excpetion";

export class OrganizationService extends BaseService {
    async CreateOrganization(entity: Organization, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let has = await ctx.Organization.Any(x => x.name == $args1, { $args1: entity.name });
            if (has) {
                throw new ServiceException(`已经存在名称为【${entity.name}】的组织！`);
            }
            has = await ctx.Organization.Any(x => x.code == $args1, { $args1: entity.code });
            if (has) {
                throw new ServiceException(`已经存在代码为【${entity.code}】的组织！`);
            }

            let d = new Organization();
            d.ConverToEntity(entity);
            d.id = Guid.GetGuid();
            d.createTime = Date.now();
           // d.status = null;
            d.isDelete = false;
            return ctx.Create(d);
        });
    }
    async UpdateOrganization(entity: Organization, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let has = await ctx.Organization.Any(x => x.name == $args1 && x.id != $args2 && x.isDelete ==$args3, { $args1: entity.name, $args2: entity.id , $args3: false});
            if (has) {
                throw new ServiceException(`已经存在名称为【${entity.name}】的组织！`);
            }
            has = await ctx.Organization.Any(x => x.code == $args1 && x.id != $args2 && x.isDelete ==$args3, { $args1: entity.code, $args2: entity.id, $args3: false });
            if (has) {
                throw new ServiceException(`已经存在代码为【${entity.code}】的组织！`);
            }

            let d = new Organization();
            d.ConverToEntity(entity);
            return ctx.Update(d);
        });
    }

    async DeleteOrganization(entity: Organization, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new Organization();
            d.ConverToEntity(entity);
            return ctx.Delete(d);
        });
    }

    async GetOrganizationById(id: string) {
        let ctx = new ApiDataContext();
        let r = await ctx.Organization.First(x => x.id == $args1, { $args1: id });
        r.orgTree = await ctx.OrganizationTree.First(x => x.objectId == $args1, { $args1: r.id });
        return r;
    }
    async QueryOrganization(params: OrganizationQueryParams) {
        let q = this.GetQueryOrganizationCtx(params);
        let total = await q.Count();

        let q2 = this.GetQueryOrganizationCtx(params);
        if (params.countOfPage && params.pageIndex) {
            q2 = q2.Take(params.countOfPage).Skip(params.pageIndex - 1) as any;
        }
        let list = await q2.OrderByDesc(x => x.createTime).ToList();

        return {
            total,
            list
        };
    }

    private GetQueryOrganizationCtx(params: OrganizationQueryParams) {
        let ctx = new ApiDataContext();
        let q = ctx.Organization as IQueryObject<Organization>;
        q = q.Where(x => x.isDelete == $args1, { $args1: false });
        if (params) {
            if (params.code) {
                q = q.Where(x => x.code == $args1, { $args1: params.code });
            }
            if (params.name) {
                q = q.Where(x => x.name.indexOf($args1), { $args1: params.name });
            }
            if (params.status) {
                q = q.Where(x => x.status == $args1, { $args1: params.status });
            }
        }
        return q;
    }

}

export interface OrganizationQueryParams extends QueryParamsBase {
    code?: string;
    name?: string;
    status?:string;
}